/**
 * 
 */
package com.google.code.netz.wfe.api;

import java.util.UUID;

import com.google.code.netz.wfe.model.Activity;
import com.google.code.netz.wfe.model.ICase;
import com.google.code.netz.wfe.model.Resource;
import com.google.code.netz.wfe.model.State;
import com.google.code.netz.wfe.model.Transition;
import com.google.code.netz.wfe.model.WorkItem;

/**
 * Contract exposed to the clients of ICase system.
 * 
 * @author <a href='mailto:rahul.thakur.xdev@gmail.com'>Rahul Thakur</a>
 * @since 1.0
 * @version $Id$
 */
public interface IWorkflowEngine {

	/**
	 * ICase lifecycle method that registers a CaseImpl with the ICase runtime
	 * responsible for managing CaseImpl processing.
	 * 
	 * @param kase
	 * @param resource
	 * @return
	 * @throws WorkflowException
	 */
	public <D> WorkItem<D> submit(ICase<D> kase, Resource resource) throws WorkflowException;

	/**
	 * Opens a {@link WorkItem} instance to yield an Activity. This also that
	 * the Activity is activated and executed as a part of this operation.
	 * <p>
	 * Ideally, this operational is transactional.
	 * 
	 * @param wi
	 * @param resource
	 * @return
	 * @throws WorkflowException
	 */
	public Activity open(WorkItem wi, Resource resource) throws WorkflowException;

	/**
	 * Closes a specified Activity.
	 * <p>
	 * The operation verifies if the specified Resource is authorised to close
	 * the specified activity.
	 * 
	 * @param activity
	 * @param resource
	 * @throws WorkflowException
	 */
	public void close(Activity activity, Resource resource) throws WorkflowException;

	/**
	 * Fires a Transition if it is enabled, i.e, if all inputs to the specified
	 * Transition have a IToken.
	 * <p>
	 * A firing Transition a IToken from each of the input places, processes the
	 * Workflow document/data, and then adds Tokens to appropriate output
	 * Places.
	 * 
	 * @param transition
	 * @param resource
	 * @throws WorkflowException
	 */
	public void fire(Transition transition, Resource resource) throws WorkflowException;

	/**
	 * ICase lifecycle method that suspends a CaseImpl which is active.
	 * 
	 * @param kase
	 * @param resource
	 * @throws WorkflowException
	 */
	public <D> void suspend(ICase<D> kase, Resource resource) throws WorkflowException;

	/**
	 * ICase lifecycle method that resumes the processing of a CaseImpl from the
	 * point where it was suspended.
	 * 
	 * @param kase
	 * @param resource
	 * @throws WorkflowException
	 */
	public <D> void resume(ICase<D> kase, Resource resource) throws WorkflowException;

	/**
	 * ICase lifecycle method that terminates the processing of a case. The
	 * CaseImpl is no longer active once {@link #close(ICase)} is called, and a
	 * fresh instance of a similar CaseImpl needs to be submitted.
	 * 
	 * @param kase
	 * @param resource
	 * @throws WorkflowException
	 */
	public <D> void close(ICase<D> kase, Resource resource) throws WorkflowException;

	/**
	 * Base on a CaseImpl's UUID, this method is used to query and obtain a
	 * CaseImpl's state.
	 * 
	 * @param kaseId
	 * @param resource
	 * @return
	 * @throws WorkflowException
	 */
	public State query(UUID kaseId, Resource resource) throws WorkflowException;

}
